/*************************************************************************
 *                                                                       *
 * This file is part of the FreeMAPs distribution.  For full copyright   *
 * information, see COPYRIGHT and COPYING.LESSER.                        *
 *                                                                       *
 * Author:           sqbang                                              *
 * Email:            sqbang@ustc.edu                                     *
 * Date:             2013.09.30                                          *
 *                                                                       *
 *************************************************************************/

#ifndef FreeMAPs_include_COMMON_info_MeshInfo_h
#define FreeMAPs_include_COMMON_info_MeshInfo_h

#include "FreeMAPsConfig.h"

//COMMON headers
#include "COMMON/base/StateIndicator.h"
#include "COMMON/enum/MeshType.h"

namespace FreeMAPs
{

//forward declarations
class StructuredMeshInfo;
class UnstructuredMeshInfo;

/**
 * @brief MeshInfo used to set the mesh information that the program will deal with.
 *
 * the simulation process's cornerstone is mesh. two type mesh named structured and unstructured
 * mesh are supported now, and a bottom library supported for the mesh are supplied.
 */
class MeshInfo : public StateIndicator
{
public:

    explicit
    MeshInfo(
        const std::string& object_name);

    ~MeshInfo();

public:

    inline MeshType
    get_mesh_type() const;

    inline void
    set_mesh_type(const MeshType mesh_type);

    inline bool
    use_structured_mesh() const;

    inline bool
    use_unstructured_mesh() const;

    inline const StructuredMeshInfo*
    get_structured_mesh_info() const;

    inline StructuredMeshInfo*
    get_structured_mesh_info();

    inline const UnstructuredMeshInfo*
    get_unstructured_mesh_info() const;

    inline UnstructuredMeshInfo*
    get_unstructured_mesh_info();


public:
    /*
     * build all the point objects
     */
    void
    create_objects ();

    const std::string
    get_mesh_file_location() const;


public:

    void
    clear();

    /**
     * some key is used in structured mesh.
     * so if not use structured mesh, error will be reported.
     */
    void
    check_structured_mesh_is_used (
        const InputDatabase* db,
        const std::string& key) const;

    void
    get_from_input (
        const InputDatabase* db);

    friend std::ostream&
    operator << (
        std::ostream& os,
        const MeshInfo& rhs);

    bool
    check_all_info_db(const InputDatabase* db);


private:

    typedef StateIndicator Parent;

    /*
     * tells use the structured mesh or unstructured mesh.
     */
    MeshType d_mesh_type;
    StructuredMeshInfo* d_structured_mesh_info;
    UnstructuredMeshInfo* d_unstructured_mesh_info;
};

}

#include "COMMON/info/MeshInfo.inl"

#endif
